﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
using System.Windows.Forms;
using System.Data;
using System.IO;

namespace Application_erabliere.Utilitaires
{
    public class Commandehelper
    {
        #region Propriété
        private static string databaseIP = string.Empty;

        public static string DatabaseIP
        {
            get { return Commandehelper.databaseIP; }
        }
        private static string databaseName = string.Empty;

        public static string DatabaseName
        {
            get { return Commandehelper.databaseName; }
        }
        private static string databaseUser = string.Empty;

        public static string DatabaseUser
        {
            get { return Commandehelper.databaseUser; }
        }
        private static string databasePassword = string.Empty;

        public static string DatabasePassword
        {
            get { return Commandehelper.databasePassword; }
        }
       


        /// <summary>
        /// Chaine permettant la connexion a la base de données.
        /// </summary>
        public static string connexionBD
        {
            get { return databaseIP + databaseName + databaseUser + databasePassword; }
        }
        #endregion

        #region Charger les constantes

        /// <summary>
        /// Appeler cette méthode au lancement de l'application.
        /// </summary>
        /// <param name="pFichier">Fichier qui se nomme config.txt</param>
        public static void ChargerLesConstantes(string pFichier)
        {
            StreamReader objStream = new StreamReader(pFichier);
            while (!objStream.EndOfStream)
            {
                string temp = objStream.ReadLine();
                if (temp.StartsWith("#"))
                    break;
                if (temp.StartsWith("SERVER"))
                    databaseIP = temp;
                else if (temp.StartsWith("DATABASE"))
                    databaseName = temp;
                else if (temp.StartsWith("UID"))
                    databaseUser = temp;
                else if (temp.StartsWith("PASSWORD"))
                {
                    string[] tabtemp = temp.Split('=');

                    databasePassword = tabtemp[0] + "=" + DecripterMotDePasse(tabtemp[1]);

                }
                
                /* A continuer au fur et a mesure que l'on rajoute des champs*/

                //---------------------------------------------------------------

            } 
            
            objStream.Close();

        }
#endregion

        #region Décriptage du mot de passe
        /// <summary>
        /// Décripte le mot de passe pour la connexion a la base de données
        /// </summary>
        /// <param name="pPassword">mot de passe codée</param>
        /// <returns>retourne le mot de passe non-encrypter</returns>
        private static string DecripterMotDePasse(string pPassword)
        {
            string chaineARetourner = string.Empty;
            foreach (char item in pPassword)
            {
                chaineARetourner += (char)(item - 'A');
            }

            return chaineARetourner;
        }

#endregion

        /// <summary>
        /// Exécute une requete sql peut importe laquelle.
        /// </summary>
        /// <param name="pCommandSQL">Requete SQL a traiter. Doit se terminer par un ;</param>
        /// <returns>Retourne une liste générique de tableau d'objet</returns>
        public static List<object[]> RequeteSQL(string pCommandSQL)
        {
            if (pCommandSQL[pCommandSQL.Length - 1] != ';')
            {
                MessageBox.Show("La rêquete doit se terminer par un ';'", "Erreur", MessageBoxButtons.OK);
                return null;
               
            }

            //pCommandSQL = pCommandSQL.ToLower();


            List<object[]> m_colObject = new List<object[]>();


            /*  Instanciation de la connexion   */
            MySqlConnection connection = new MySqlConnection(connexionBD);
            MySqlCommand command = connection.CreateCommand();
            /*  ==Ouverture de la connexion==   */
            connection.Open();
            command.CommandText = pCommandSQL;
            try
            {
                /*      Si Rêquete Select           */
                if (pCommandSQL.ToLower().StartsWith("select"))
                {

                    MySqlDataReader Reader;
                    Reader = command.ExecuteReader(CommandBehavior.CloseConnection);
                    m_colObject = new List<object[]>();

                    while (Reader.Read())
                    {
                        object[] tabObject = new object[Reader.FieldCount];
                        for (int i = 0; i < Reader.FieldCount; i++)
                        {
                            tabObject[i] = Reader[i];
                        }
                        m_colObject.Add(tabObject);
                    }

                }
                /* Si requete Insert */
                else if (pCommandSQL.ToLower().StartsWith("insert"))
                {
                    command.ExecuteNonQuery();
                    m_colObject = null;
                }
                else if (pCommandSQL.ToLower().StartsWith("update"))
                {
                    command.ExecuteNonQuery();
                    m_colObject = null;

                }
                else if (pCommandSQL.ToLower().StartsWith("delete"))
                {
                    command.ExecuteNonQuery();
                    m_colObject = null;
                }

            }
            catch (Exception)
            {

                MessageBox.Show("Erreur dans la synthaxe de la requête SQL.");
                return null;
            }
            connection.Close();
            return m_colObject;
        }

        /// <summary>
        /// Cette méthode ne peux pas retourner plus que une valeur. Ideal pour les requetes Insert, Update ou delete. 
        /// </summary>
        /// <param name="pString">requete SQL a exécuté</param>
        /// <returns>une valeur qui la majorité du doit doit etre égal a null</returns>
        public static object RequeteSqlSimple(string pString)
        {
            if (pString[pString.Length - 1] != ';')
            {
                MessageBox.Show("La rêquete doit se terminer par un ';'", "Erreur", MessageBoxButtons.OK);
                return null;

            }

            MySqlConnection connection = new MySqlConnection(connexionBD);
            MySqlCommand command = connection.CreateCommand();
            /*  ==Ouverture de la connexion==   */
            connection.Open();
            command.CommandText = pString;
            object objobject = command.ExecuteScalar();
            connection.Close();
            return objobject;
            
        }

        /// <summary>
        /// Rempli un listview dont chaque colonnes est en ordre avec le shéma de la base de données
        /// </summary>
        /// <param name="pObjLsv">Listview a remplir</param>
        /// <param name="pNomTable">Table a extraire les données</param>
        public static void RemplirLsv(ListView pObjLsv, string pNomTable)
        {
            /*  Instanciation de la connexion   */
            MySqlConnection connection = new MySqlConnection(connexionBD);
            MySqlCommand command = connection.CreateCommand();
            /*  ==Ouverture de la connexion==   */
            connection.Open();
            command.CommandText = "select * from "+pNomTable+";";
            MySqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
            pObjLsv.Items.Clear();
            while (reader.Read())
            {
                ListViewItem objitem = new ListViewItem(reader[1].ToString());
                for (int i = 2; i < reader.FieldCount; i++)
                {
                    objitem.SubItems.Add(reader[i].ToString());
                }
                pObjLsv.Items.Add(objitem);

            }



            /*    Fermeture de la connexion    */
            connection.Close();
        }

        /// <summary>
        /// Ouvre une connexion a la base de données.
        /// S'assurer de fermer la connexion une fois fini.
        /// </summary>
        /// <returns>MySqlConnection, a placé dans le paramètres de la méthode FermerConnexionBD</returns>
        public static MySqlConnection OuvrirConnexionBD()
        {
            if (connexionBD == null)
            {
                MessageBox.Show("Chaine de connexion vide. Veuillez charger les constantes");
                return null;
            }
                
            MySqlConnection connection = new MySqlConnection(connexionBD);
            try
            {
                
                connection.Open();
            }
            catch
            {
                MessageBox.Show("Erreur dans la chaine de connexion");
            } 
            return connection;
        }

        /// <summary>
        /// Ferme une connexion qui était ouverte auparavant grace a la méthode OuvrirConnexionDB
        /// </summary>
        /// <param name="pConnexion">Connexion provenant de la méthode OuvrirConnexionDB</param>
        public static void FermerConnexionBD(MySqlConnection pConnexion)
        {
            if(pConnexion != null)
                pConnexion.Close();
        }
    }
}
